package com.smart.community.region.controller;

import com.smart.community.feign.region.dto.RegionDTO;
import com.smart.community.feign.region.dto.RegionTreeDTO;
import com.smart.community.region.service.IRegionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 区域Feign接口实现Controller
 * 提供区域相关的Feign接口，不进行权限验证
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/feign/region")
public class RegionFeignController {

    @Autowired
    private IRegionService regionService;

    /**
     * 获取区域树形结构（支持按需加载）
     * 
     * @param parentId 父区域ID，不传则获取顶级区域
     * @return 区域树形结构列表
     */
    @GetMapping("/region/tree")
    public List<RegionTreeDTO> getRegionTree(@RequestParam(value = "parentId", required = false) Long parentId) {
        log.info("Feign接口：获取区域树形结构，parentId: {}", parentId);
        try {
            return regionService.getRegionTreeForFeign(parentId);
        } catch (Exception e) {
            log.error("Feign接口：获取区域树形结构失败", e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 获取指定区域及其所有子区域ID（递归到末梢，包含自身）
     * 用于数据区域范围查询
     *
     * @param regionId 区域ID
     * @return 区域ID列表（包含自身与所有下级）
     */
    @GetMapping("/region/{regionId}/descendant-ids")
    public List<Long> getRegionAndDescendantIds(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：获取区域及其所有子区域ID，regionId: {}", regionId);
        try {
            List<Long> ids = regionService.getAllChildRegionIds(regionId);
            java.util.ArrayList<Long> result = new java.util.ArrayList<>(ids == null ? java.util.Collections.emptyList() : ids);
            if (regionId != null && !result.contains(regionId)) {
                result.add(regionId);
            }
            log.info("Feign接口：获取区域及其所有子区域ID成功，regionId:{}，总数量:{}", regionId, result.size());
            return result;
        } catch (Exception e) {
            log.error("Feign接口：获取区域及其所有子区域ID失败，regionId: {}", regionId, e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 获取区域完整树形结构（递归查询所有子区域）
     * 
     * @param parentId 父区域ID，不传则获取所有顶级区域
     * @return 完整的区域树形结构列表
     */
    @GetMapping("/region/tree/complete")
    public List<RegionTreeDTO> getCompleteRegionTree(@RequestParam(value = "parentId", required = false) Long parentId) {
        log.info("Feign接口：获取区域完整树形结构，parentId: {}", parentId);
        try {
            return regionService.getCompleteRegionTreeForFeign(parentId);
        } catch (Exception e) {
            log.error("Feign接口：获取区域完整树形结构失败", e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 根据区域ID获取区域信息
     * 
     * @param regionId 区域ID
     * @return 区域信息
     */
    @GetMapping("/region/{regionId}")
    public RegionDTO getRegionById(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：根据区域ID获取区域信息，regionId: {}", regionId);
        try {
            return regionService.getRegionByIdForFeign(regionId);
        } catch (Exception e) {
            log.error("Feign接口：根据区域ID获取区域信息失败，regionId: {}", regionId, e);
            return null;
        }
    }

    /**
     * 根据区域编码获取区域信息
     * 
     * @param regionCode 区域编码
     * @return 区域信息
     */
    @GetMapping("/region/code/{regionCode}")
    public RegionDTO getRegionByCode(@PathVariable("regionCode") String regionCode) {
        log.info("Feign接口：根据区域编码获取区域信息，regionCode: {}", regionCode);
        try {
            return regionService.getRegionByCodeForFeign(regionCode);
        } catch (Exception e) {
            log.error("Feign接口：根据区域编码获取区域信息失败，regionCode: {}", regionCode, e);
            return null;
        }
    }

    /**
     * 根据区域类型获取区域列表
     * 
     * @param regionType 区域类型：1-省，2-市，3-区县，4-街道，5-社区
     * @return 区域列表
     */
    @GetMapping("/region/type/{regionType}")
    public List<RegionDTO> getRegionsByType(@PathVariable("regionType") Integer regionType) {
        log.info("Feign接口：根据区域类型获取区域列表，regionType: {}", regionType);
        try {
            return regionService.getRegionsByTypeForFeign(regionType);
        } catch (Exception e) {
            log.error("Feign接口：根据区域类型获取区域列表失败，regionType: {}", regionType, e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 获取子区域列表
     * 
     * @param regionId 区域ID
     * @return 子区域列表
     * @throws Exception 
     */
    @GetMapping("/region/{regionId}/children")
    public List<RegionDTO> getChildRegions(@PathVariable("regionId") Long regionId) throws Exception {
    	return regionService.getChildRegionsForFeign(regionId);
    }

    /**
     * 获取区域层级路径
     * 
     * @param regionId 区域ID
     * @return 区域层级路径列表
     */
    @GetMapping("/region/{regionId}/path")
    public List<RegionDTO> getRegionPath(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：获取区域层级路径，regionId: {}", regionId);
        try {
            return regionService.getRegionPathForFeign(regionId);
        } catch (Exception e) {
            log.error("Feign接口：获取区域层级路径失败，regionId: {}", regionId, e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 批量获取区域信息
     * 
     * @param regionIds 区域ID列表
     * @return 区域信息列表
     */
    @PostMapping("/region/batch")
    public List<RegionDTO> getRegionsByIds(@RequestBody List<Long> regionIds) {
        log.info("Feign接口：批量获取区域信息，regionIds: {}", regionIds);
        try {
            return regionService.getRegionsByIdsForFeign(regionIds);
        } catch (Exception e) {
            log.error("Feign接口：批量获取区域信息失败，regionIds: {}", regionIds, e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 检查区域编码是否存在
     * 
     * @param regionCode 区域编码
     * @param excludeRegionId 排除的区域ID
     * @return 是否存在
     */
    @GetMapping("/region/check/code")
    public Boolean checkRegionCodeExists(
            @RequestParam("regionCode") String regionCode,
            @RequestParam(value = "excludeRegionId", required = false) Long excludeRegionId) {
        log.info("Feign接口：检查区域编码是否存在，regionCode: {}, excludeRegionId: {}", regionCode, excludeRegionId);
        try {
            return regionService.checkRegionCodeExistsForFeign(regionCode, excludeRegionId);
        } catch (Exception e) {
            log.error("Feign接口：检查区域编码是否存在失败，regionCode: {}", regionCode, e);
            return false;
        }
    }

    /**
     * 根据区域名称模糊查询区域列表
     * 
     * @param regionName 区域名称
     * @return 区域列表
     */
    @GetMapping("/region/search/name")
    public List<RegionDTO> searchRegionsByName(@RequestParam("regionName") String regionName) {
        log.info("Feign接口：根据区域名称模糊查询区域列表，regionName: {}", regionName);
        try {
            return regionService.searchRegionsByNameForFeign(regionName);
        } catch (Exception e) {
            log.error("Feign接口：根据区域名称模糊查询区域列表失败，regionName: {}", regionName, e);
            return new java.util.ArrayList<>();
        }
    }

    /**
     * 获取区域统计信息
     * 
     * @param regionId 区域ID
     * @return 区域统计信息
     */
    @GetMapping("/region/{regionId}/stats")
    public Object getRegionStats(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：获取区域统计信息，regionId: {}", regionId);
        try {
            return regionService.getRegionStatsForFeign(regionId);
        } catch (Exception e) {
            log.error("Feign接口：获取区域统计信息失败，regionId: {}", regionId, e);
            return null;
        }
    }

    /**
     * 获取所有区域统计信息
     * 
     * @return 所有区域统计信息
     */
    @GetMapping("/region/statistics")
    public Object getAllRegionStatistics() {
        log.info("Feign接口：获取所有区域统计信息");
        try {
            return regionService.getAllRegionStatisticsForFeign();
        } catch (Exception e) {
            log.error("Feign接口：获取所有区域统计信息失败", e);
            return null;
        }
    }

    /**
     * 清除区域缓存
     * 
     * @param regionId 区域ID
     * @return 清除结果
     */
    @DeleteMapping("/region/cache/{regionId}")
    public Boolean clearRegionCache(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：清除区域缓存，regionId: {}", regionId);
        try {
            return regionService.clearRegionCacheForFeign(regionId);
        } catch (Exception e) {
            log.error("Feign接口：清除区域缓存失败，regionId: {}", regionId, e);
            return false;
        }
    }

    /**
     * 清除所有区域缓存
     * 
     * @return 清除结果
     */
    @DeleteMapping("/region/cache/all")
    public Boolean clearAllRegionCache() {
        log.info("Feign接口：清除所有区域缓存");
        try {
            return regionService.clearAllRegionCacheForFeign();
        } catch (Exception e) {
            log.error("Feign接口：清除所有区域缓存失败", e);
            return false;
        }
    }

    /**
     * 刷新区域统计数据
     * 
     * @param regionId 区域ID
     * @return 刷新结果
     */
    @PostMapping("/region/{regionId}/refresh-stats")
    public Boolean refreshRegionStats(@PathVariable("regionId") Long regionId) {
        log.info("Feign接口：刷新区域统计数据，regionId: {}", regionId);
        try {
            return regionService.refreshRegionStatsForFeign(regionId);
        } catch (Exception e) {
            log.error("Feign接口：刷新区域统计数据失败，regionId: {}", regionId, e);
            return false;
        }
    }
}
